home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 2010 April
/
PCWorld0410.iso
/
pluginy Firefox
/
1122
/
1122.xpi
/
chrome
/
tabmixplus.jar
/
content
/
tabmixplus
/
tab
/
tab.js
next >
Wrap
Text File
|
2009-10-11
|
76KB
|
1,842 lines
// code based on Tab X 0.5 enhanced version by Morac, modified by Hemiola SUN, later CPU & onemen
var nsIPrefServiceObj = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
var tabxBranch = "extensions.tabmix.";
var tabxPrefs = nsIPrefServiceObj.getBranch(tabxBranch);
var gTMPprefObserver = null;
var gTabBarWidth = -1;
var addtabx;
var tabxleft;
var tabscroll;
var gWidthFitTitle;
var gTabbarPosition = 0;
var gSingleWindowMode;
var alwaysNewTab;
var gHideTabBar;
var gPreventUpdate;
function TMupdateSettings(start) {
// getBrowser() here for Firefox 3.0
var tabBrowser = getBrowser();
if (!tabBrowser || tabxPrefs.prefHasUserValue("setDefault") || gPreventUpdate == true)
return;
var tabBar = tabBrowser.mTabContainer;
var i;
addtabx = TMP_getIntPref (tabxBranch, "tabXMode", 1);
// in old version we use tabXMode = 0 to disable the button
if (addtabx < 1 || addtabx > 5) {
addtabx = 1;
tabxPrefs.setIntPref("tabXMode", 1);
return;
}
tabxleft = TMP_getBoolPref(tabxBranch, "tabXLeft", false);
tabscroll = TMP_getIntPref (tabxBranch, "tabBarMode", 1);
if (tabscroll < 0 || tabscroll > 3 || (tabscroll != 1 && "TreeStyleTabBrowser" in window)) {
tabxPrefs.setIntPref("tabBarMode", 1);
return;
}
tabBar.mTabMaxWidth = gTabmixPrefs.getIntPref("browser.tabs.tabMaxWidth");
tabBar.mTabMinWidth = gTabmixPrefs.getIntPref("browser.tabs.tabMinWidth");
if (tabBar.mTabMaxWidth < tabBar.mTabMinWidth) {
tabxPrefs.setBoolPref("setDefault", true);
gTabmixPrefs.setIntPref("browser.tabs.tabMaxWidth", tabBar.mTabMinWidth);
gTabmixPrefs.setIntPref("browser.tabs.tabMinWidth", tabBar.mTabMaxWidth);
tabxPrefs.clearUserPref("setDefault"); // this trigger TMupdateSettings
return;
}
gWidthFitTitle = TMP_getBoolPref(tabxBranch, "flexTabs", false) &&
(tabBar.mTabMaxWidth != tabBar.mTabMinWidth);
alwaysNewTab = TMP_getIntPref (tabxBranch, "speLink", 0);
var currentVisible = start ? true : tabBar.isTabVisible(tabBrowser.mCurrentTab._tPos);
if (!gisToolbarMode) {
var direction = gTabbarPosition == 1 ? "rtl" : "ltr";
tabBrowser.mTabBox.setAttribute("dir", direction);
}
if (tabBar.mAllTabsPopup) { // mAllTabsPopup will remove in firfox 3.5 or later
// fix bug in positioning the popup off screen or on the button when window is not maximize or when tab bar is in the bottom
TMP_setItem(tabBar.mAllTabsPopup, "position",
(window.windowState != window.STATE_MAXIMIZED || gTabbarPosition == 1) ? "start_before" : "after_end");
}
switch ( tabscroll ) {
case 0:
tabBar.setAttribute("flowing", "singlebar");
tabBar.overflow = false;
break;
case 1:
if (!tabBar.hasAttribute("scrollbutton-up"))
tabBar.setAttribute("scrollbutton-up", "left");
case 3:
if (tabBar.getAttribute("flowing") != "scrollbutton") {
tabBar.setAttribute("flowing", "scrollbutton");
tabBar.overflow = tabBar.canScrollTabsLeft || tabBar.canScrollTabsRight;
}
break;
case 2:
if (tabBar.getAttribute("flowing") != "multibar") {
tabBar.setAttribute("flowing", "multibar");
if (!start || tabBar.collapsedTabs > 0)
tabBar.collapsedTabs = 0;
}
break;
}
/* Fix problem with multi-row when tab width is very small
need to findout how to remove extra space when display is block or inline
then we don't have to fix the tab height
*/
if (tabscroll == 2 && tabBar.mTabMaxWidth < 50)
TMP_setItem(tabBar, "inline", true);
else
tabBar.removeAttribute("inline");
if (tabscroll != 1 && tabBar.hasAttribute("scrollbutton-up"))
tabBar.removeAttribute("scrollbutton-up");
var showCloseButton = TMP_getBoolPref(tabxBranch, "tabXMode.enable", true);
for (i = 0; i < tabBar.childNodes.length; i++) {
var aTab = tabBar.childNodes[i];
if (!aTab.hasAttribute("faviconized")) {
aTab.maxWidth = tabBar.mTabMaxWidth;
aTab.style.maxWidth = tabBar.mTabMaxWidth + "px";
aTab.minWidth = tabBar.mTabMinWidth;
}
if (gWidthFitTitle) {
if (aTab.hasAttribute("width")) aTab.removeAttribute("width");
if (aTab.hasAttribute("flex")) aTab.removeAttribute("flex");
} else {
TMP_setItem(aTab, "width", "0");
TMP_setItem(aTab, "flex", "100");
}
if ( alwaysNewTab == 1) {
// when we can change user locked / unlock tabs
var changeUserLockStatus = (start && aTab.getAttribute("_locked") != "false") ||
(!start && tabBar.getAttribute("lockAllTab") != "true")
if (changeUserLockStatus) {
aTab.setAttribute("locked", "true");
aTab.removeAttribute("_locked");
}
}
else if ( tabBar.getAttribute("lockAllTab") == "true" ) {
aTab.removeAttribute("locked");
aTab.removeAttribute("_locked");
}
SessionManager.updateTabProp(aTab);
if (showCloseButton) {
var closeButtonOptions = ["no-button","always","showhover","current","current_hover","always"];
aTab.setAttribute("tabx", closeButtonOptions[addtabx]);
}
else
aTab.removeAttribute("tabx");
if (tabxleft)
aTab.setAttribute("tabxleft", "on");
else
aTab.removeAttribute("tabxleft");
}
// show on tabbar
tabBar.setAttribute("closebutton", !TMP_getBoolPref(tabxBranch, "hideTabBarButton", true));
tabBar.setAttribute("hideAllTabsButton", TMP_getBoolPref(tabxBranch, "hideAllTabsButton", false));
tabBar.setAttribute("tabBarSpace", TMP_getBoolPref(tabxBranch, "tabBarSpace", false));
tabBar.setAttribute("extraIcons", TMP_getBoolPref(tabxBranch, "extraIcons", true));
tabBar.setAttribute("lockAllTab", alwaysNewTab == 1 );
var showNewTabButton = tabxPrefs.getBoolPref("newTabButton");
tabBar.setAttribute("newTabButton", showNewTabButton);
tabBar._checkNewtabButtonvisibility = gIsFirefox35 && showNewTabButton && tabxPrefs.getIntPref("newTabButton.position") == 2;
// user changed maxRow number
if (tabBar.tabstrip.style.maxHeight && gBrowser.getStripVisibility() && tabBar.collapsedTabs > 0) {
var currentMaxRow = tabBar.lastTabRowNumber;
var rowDiff = tabBar.maxRow - currentMaxRow;
while (tabBar.collapsedTabs > 0 && rowDiff > 0) {
tabBar.rowScroll(-1);
rowDiff--;
}
}
if (start && "isLoadHomePage" in window) {
window.setTimeout(tabBarScrollStatus, 0);
delete window.isLoadHomePage;
}
else
tabBarScrollStatus();
window.setTimeout( function TMupdateSettings_adjustScroll(_currentVisible) {
if (_currentVisible) {
tabBar.ensureTabIsVisible(tabBar.selectedIndex);
}
tabBar.adjustScrollTabsLeft();
tabBar.adjustScrollTabsRight();
checkBeforeAndAfter();
//XXX underline the label bleed over the end when tab is to small and we have close button on the tab !!!!????
toggleUnderlineTabsLabel();
}, 50, currentVisible);
}
/*
XXX underline the label bleed over the end when tab is to small and we have close button on the tab !!!!????
workaround is to remove underline when tab is too small
when to set hideunderline
A. tababr is visibile
B. !gWidthFitTitle and width < 70
C. gWidthFitTitle and maxwidth < 70
*/
function toggleUnderlineTabsLabel() {
var tabBar = gBrowser.mTabContainer;
if (tabBar.boxObject.width == 0)
return;
var _tinywidth;
if (tabBar.mTabMaxWidth < 70)
_tinywidth = true;
else {
var tab = tabBar.childNodes[tabBar.collapsedTabs];
if (tab)
_tinywidth = !gWidthFitTitle && tab.boxObject.width < 70;
}
TMP_setItem(tabBar, "hideunderline", _tinywidth || null);
}
var gVisibleRows = 1;
function tabBarScrollStatus () {
/*
* multibar is not affected by RTL direction we only need to consider RTL when we are in one row mode
*/
var tabBar = gBrowser.mTabContainer;
if (tabBar.boxObject.width == 0)
return;
tabBar.adjustNewtabButtonvisibility();
tabBar.adjustScrollTabsLeft();
var multibar, lastTabRow, currentMultibar = tabBar.getAttribute("multibar") || null;
if (tabscroll == 2) {
// we need to check this when last row of tabs is empty and we still have hidden row on top
// this can occur when we close last tab in the last row or when some tab changed width
if ( tabBar.getAttribute("multibar") == "scrollbar" &&
tabBar.collapsedTabs > 0 && tabBar.lastTabRowNumber < tabBar.maxRow) {
tabBar.rowScroll(-1);
}
[multibar, lastTabRow] = getMultiRowAttribute();
}
else {
[multibar, lastTabRow] = [null, 1];
}
if (currentMultibar != multibar) {
TMP_setItem(tabBar, "multibar", multibar); // if multibar is null we remove the attribute
if (gisToolbarMode)
TMP_setItem("tabs-toolbar", "multibar", multibar);
}
setTabBarHeight(lastTabRow);
tabBar.adjustScrollTabsRight();
}
function getMultiRowAttribute () {
var tabBar = gBrowser.mTabContainer;
var maxRow = tabBar.maxRow;
if (tabBar.collapsedTabs > 0)
return ["scrollbar", maxRow];
if (!gBrowser.getStripVisibility())
return [null, 1];
var lastTabRow;
if (tabBar.hasAttribute("multibar")) {
tabBar.adjustNewtabButtonvisibility();
var lastTabRow = tabBar.lastTabRowNumber;
if (lastTabRow == 1)
return [null, 1]; // removeAttribute "multibar"
if (lastTabRow > tabBar.maxRow)
return ["scrollbar", maxRow];
}
else {
if (tabBar.lastTabVisible)
return [null, 1]; // removeAttribute "multibar"
// init multibar
tabBar.setAttribute("multibar", "true");
tabBar.adjustNewtabButtonvisibility();
// remember that tabBar.lastTabRowNumber may change when we set "multibar" to true
lastTabRow = tabBar.lastTabRowNumber;
if (lastTabRow > tabBar.maxRow)
return ["scrollbar", maxRow];
}
return ["true", lastTabRow];
}
var windowStyle = {exist:false, value:null};
var tabBarHeights = {};
function setTabBarHeight (aRows) {
if (gVisibleRows == aRows)
return;
gVisibleRows = aRows;
var tabBar = gBrowser.mTabContainer;
var tabstrip = tabBar.tabstrip;
if (aRows == 1) {
if (tabstrip.hasAttribute("style")) {
tabstrip.style.removeProperty("max-height");
tabstrip.style.removeProperty("height");
}
if (tabBar.hasAttribute("style")) {
tabBar.style.removeProperty("max-height");
tabBar.style.removeProperty("height");
}
if (windowStyle.exist)
TMP_setItem(document.getElementById("main-window"), "style", windowStyle.value);
return;
}
var newHeight;
if (aRows in tabBarHeights)
newHeight = tabBarHeights[aRows];
else {
if (tabBar.tabstripInnerbox) {
if (tabBar.getAttribute("multibar") == "scrollbar")
// we never get this..... we always get row x with multibar=true before we get to the max row
// once we get to max row and set multibar=scrollbar gVisibleRows == lastTabRow in tabBarScrollStatus
newHeight = tabBarHeights[aRows] = (tabBar.tabstripInnerbox.boxObject.height/tabBar.lastTabRowNumber) * aRows;
else
newHeight = tabBarHeights[aRows] = tabBar.tabstripInnerbox.boxObject.height;
}
else
newHeight = tabBarHeights[aRows] = getRowHeight() * aRows;
}
if (tabstrip.style.maxHeight != tabstrip.style.height || tabstrip.style.maxHeight != newHeight + "px") {
tabstrip.style.setProperty("max-height",newHeight + "px", "important");
tabstrip.style.setProperty("height",newHeight + "px", "important");
var tabsBottom = document.getAnonymousElementByAttribute(tabBar, "class", "tabs-bottom");
var tabsBottomHeight = tabsBottom ? tabsBottom.boxObject.height : 0;
var newTabbarHeight = newHeight + tabsBottomHeight;
// override fixed height set by theme to .tabbrowser-tabs class
if (tabBar.boxObject.height < newTabbarHeight || tabBar.hasAttribute("style")) {
tabBar.style.setProperty("max-height",newTabbarHeight + "px", "important");
tabBar.style.setProperty("height",newTabbarHeight + "px", "important");
}
// experimental - for theme that put tababr above the menus
// curently its only work with Vfox3 theme
if (tabstrip.boxObject.y <= gNavToolbox.boxObject.y) {
let skin = gTabmixPrefs.getCharPref("general.skins.selectedSkin");
let themes = /^(Vfox3)/;
if (themes.test(skin)) {
let mWin = document.getElementById("main-window");
if (!windowStyle.exist) {
windowStyle.exist = true;
windowStyle.value = mWin.hasAttribute("style") ? mWin.getAttribute("style") : null;
}
mWin.style.setProperty("padding-top", newTabbarHeight + "px", "important");
}
}
}
}
// Update beforeselected and afterselected attribute when we are in multi-row mode
function checkBeforeAndAfter() {
var tabBar = gBrowser.mTabContainer;
if (!tabBar.hasAttribute("multibar"))
return;
var top = tabBar.topTabY;
var tab = tabBar.selectedItem, tabRow = tabBar.getTabRowNumber(tab, top);
var prev = tab.previousSibling, next = tab.nextSibling;
if (prev && prev.localName == "tab") {
TMP_setItem(prev, "beforeselected", tabRow == tabBar.getTabRowNumber(prev, top) ? true : null);
}
if (next && next.localName == "tab") {
TMP_setItem(next, "afterselected", tabRow == tabBar.getTabRowNumber(next, top) ? true : null);
}
}
var gRowHeight = null;
function getRowHeight () {
if (gRowHeight)
return gRowHeight;
var tabBar = gBrowser.mTabContainer;
var tabs = tabBar.childNodes;
var firstTab = tabs[tabBar.collapsedTabs];
var top = tabBar.topTabY;
var lastTabRow = tabBar.lastTabRowNumber;
if (lastTabRow == 1) { // one row
if (firstTab.getAttribute("selected") == "true")
return tabBar.lastChild.boxObject.height;
else
return firstTab.boxObject.height;
}
else if (lastTabRow == 2) { // multi-row
if (tabBar.lastChild.getAttribute("selected") == "true") {
// check if previous to last tab in the 1st row
// this happen when the selected tab is the first tab in the 2nd row
var prev = tabBar.lastChild.previousSibling;
if (prev && tabBar.getTabRowNumber(prev, top) == 1)
return tabBar.lastChild.boxObject.height;
else
gRowHeight = prev.baseY - firstTab.baseY;
}
else if (firstTab.getAttribute("selected") == "true") {
// check if 2nd visible tab is in the 2nd row
// (not likely that user set tab width to more then half screen width)
var next = firstTab.nextSibling;
if (next && tabBar.getTabRowNumber(next, top) == 2)
return tabBar.lastChild.boxObject.height;
else
gRowHeight = tabBar.lastChild.baseY - next.baseY;
}
else
gRowHeight = tabBar.lastChild.baseY - firstTab.baseY;
return gRowHeight;
}
// Just in case we missed something in the above code............
var i, j;
i = j = tabBar.collapsedTabs;
if ( tabs[j] && tabs[j].getAttribute("selected") == "true" )
j++;
while (inSameRow( tabs.item(i), tabs.item(j) ) )
i++;
if ( !tabs[i] ) // only one row
if ( tabs[j] )
return tabs[j].boxObject.height;
else
return tabs[0].boxObject.height;
if ( tabs[i].getAttribute("selected") == "true" )
i++;
if ( !tabs[i] )
return tabs[i-1].boxObject.height;
gRowHeight = tabs[i].baseY - tabs[j].baseY;
return gRowHeight;
}
function inSameRow (tab1, tab2) {
if ( !tab1 || !tab2 )
return false;
var tabBar = gBrowser.mTabContainer;
var top = tabBar.topTabY;
return tabBar.getTabRowNumber(tab1, top) == tabBar.getTabRowNumber(tab2, top);
}
// call by resize event on content
function tabBarWidthChange (aEvent) {
var tabBar = gBrowser.mTabContainer;
if (tabBar.mAllTabsPopup) { // mAllTabsPopup will remov in firfox 3.5 or later
// fix bug in positioning the popup off screen or on the button when window is not maximize or when tab bar is in the bottom
TMP_setItem(tabBar.mAllTabsPopup, "position",
(window.windowState != window.STATE_MAXIMIZED || gTabbarPosition == 1) ? "start_before" : "after_end");
}
// we don't need to update scroll status when tab bar is in collapsed mode
if (tabBar.boxObject.width == 0 || window.windowState == window.STATE_MINIMIZED)
return;
// we don't need to update scroll status if resize event not trigger by width change
if ( gTabBarWidth == tabBar.boxObject.width)
return;
var tabs = tabBar.childNodes;
if (addtabx == 5 && !gWidthFitTitle)
adjustOn2ndTab.closeButton(1);
var oldCollapsed = tabBar.collapsedTabs;
var i = 0;
if ( tabscroll != 2 && gTabBarWidth < tabBar.boxObject.width ) {
while ( tabs[ oldCollapsed + i ] &&
tabs[ oldCollapsed + i ].boxObject.screenX + tabs[ oldCollapsed + i ].boxObject.width <
tabBar.tabstrip.boxObject.screenX + tabBar.tabstrip.boxObject.width ) {
i++;
}
if (tabBar.collapsedTabs > 0)
tabBar.collapsedTabs = 0;
var index = oldCollapsed + i - 1;
tabBar.ensureTabIsVisible(index);
tabBarScrollStatus();
}
else if ( tabscroll == 2 ) {
if (tabBar.collapsedTabs > 0)
tabBar.collapsedTabs = 0;
tabBarScrollStatus();
tabBar.ensureTabIsVisible(tabBar.lastChild._tPos);
tabBar.ensureTabIsVisible( oldCollapsed );
checkBeforeAndAfter();
}
else
tabBarScrollStatus();
gTabBarWidth = tabBar.boxObject.width;
}
// Function to catch changes to Tab Mix preferences and update existing windows and tabs
//
var gTMPprefObserver = {
init: function() {
var pref = "setDefault"
if (tabxPrefs.prefHasUserValue(pref))
tabxPrefs.clearUserPref(pref)
pref = "PrefObserver.error";
if (tabxPrefs.prefHasUserValue(pref))
tabxPrefs.clearUserPref(pref)
if ("TreeStyleTabBrowser" in window)
this.OBSERVING.push("extensions.treestyletab.tabbar.position");
try {
// add Observer
let prefSvc = gTabmixPrefs;
for (var i = 0; i < this.OBSERVING.length; ++i)
prefSvc.addObserver(this.OBSERVING[i], this, true);
}
catch(e) {
tmLog("prefs-Observer failed to attach:" + "\n" + e);
tabxPrefs.setBoolPref(pref, true);
}
},
// nsISupports interface implementation -- for weak-reference by pref-observer service
QueryInterface: function(iid) {
if (!iid.equals(Components.interfaces.nsISupports)
&& !iid.equals(Components.interfaces.nsISupportsWeakReference)
&& !iid.equals(Components.interfaces.nsIObserver)) {
dump("Tab Mix Plus pref-observer factory object: QI unknown interface: " + iid + "\n");
throw Components.results.NS_ERROR_NO_INTERFACE;
}
return this;
},
OBSERVING: ["extensions.tabmix.",
"browser.tabs.autoHide",
"browser.tabs.tabMinWidth",
"browser.tabs.tabMaxWidth",
"browser.tabs.tabClipWidth",
"browser.sessionstore.max_tabs_undo",
"browser.warnOnRestart",
"browser.warnOnQuit",
"browser.sessionstore.resume_from_crash",
"browser.startup.page",
"browser.link.open_external",
"browser.link.open_newwindow.restriction",
"browser.link.open_newwindow",
"browser.ctrlTab.previews"],
// removes the observer-object from service -- called when the window is no longer open
removeObservers: function() {
let prefSvc = gTabmixPrefs;
for (var i = 0; i < this.OBSERVING.length; ++i)
prefSvc.removeObserver(this.OBSERVING[i], this);
},
/* Observer-function */
/* subject: [wrapped nsISupports :: nsIPrefBranch], nsIPrefBranch Internal
topic: "changed"*/
observe: function TMP_pref_observer(subject, topic, prefName) {
// if we don't have a valid window (closed)
if ( !(typeof(document) == 'object' && document) ) {
this.removeObservers(); // remove the observer..
return; // ..and don't continue
}
var prefValue;
switch (prefName) {
case "extensions.tabmix.linkTarget":
case "extensions.tabmix.opentabfor.bookmarks":
case "extensions.tabmix.opentabfor.history":
case "extensions.tabmix.opentabfor.urlbar":
case "extensions.tabmix.middlecurrent":
case "extensions.tabmix.inversefocusLinks":
case "extensions.tabmix.inversefocusOther":
case "extensions.tabmix.loadNewInBackground":
case "extensions.tabmix.loadUrlInBackground":
case "extensions.tabmix.loadSearchInBackground":
case "extensions.tabmix.loadDuplicateInBackground":
case "extensions.tabmix.loadBookmarksGroupInBackground":
case "extensions.tabmix.filetype":
case "extensions.tabmix.warnAboutClosingTabs.timeout":
case "extensions.tabmix.sessions.crashed":
case "extensions.tabmix.disableIncompatible":
case "extensions.tabmix.appearance_tab":
case "extensions.tabmix.selected_tab":
case "extensions.tabmix.selected_sub_tab1":
case "extensions.tabmix.selected_sub_tab2":
case "extensions.tabmix.selected_sub_tab3":
case "extensions.tabmix.selected_sub_tab4":
case "extensions.tabmix.selected_sub_tab5":
case "extensions.tabmix.selected_sub_tab6":
case "extensions.tabmix.reload_time":
case "extensions.tabmix.custom_reload_time":
case "extensions.tabmix.resume_session_once":
break;
case "extensions.tabmix.undoCloseButton.menuonly":
TMP_ClosedTabs.setButtonType(gTabmixPrefs.getBoolPref(prefName));
break;
case "extensions.tabmix.focusTab":
gTabmixPrefs.setBoolPref("browser.tabs.selectOwnerOnClose", gTabmixPrefs.getIntPref(prefName) == 2);
break;
case "extensions.tabmix.disableF9Key":
this.toggleKey("key_tm_toggleFLST", prefName);
break;
case "extensions.tabmix.disableF8Key":
this.toggleKey("key_tm_slideShow", prefName);
break;
case "extensions.tabmix.hideIcons":
this.setMenuIcons();
break;
// tab appearnce
case "extensions.tabmix.currentTab":
case "extensions.tabmix.unreadTab":
case "extensions.tabmix.otherTab":
this.toggleTabStyles(prefName);
break;
case "extensions.tabmix.styles.currentTab":
case "extensions.tabmix.styles.unreadTab":
case "extensions.tabmix.styles.otherTab":
case "extensions.tabmix.styles.progressMeter":
this.setTabStyles(prefName);
break;
case "extensions.tabmix.progressMeter":
case "extensions.tabmix.noprogress":
var progressMeterOnTabs = tabxPrefs.getBoolPref("progressMeter");
gBrowser.mTabContainer.setAttribute("progressMeter", progressMeterOnTabs);
document.getElementById("statusbar-progresspanel").setAttribute("hidden", tabxPrefs.getBoolPref("noprogress") && progressMeterOnTabs);
break;
case "extensions.tabmix.flexTabs":
case "extensions.tabmix.tabXMode":
TMupdateSettings(false);
case "extensions.tabmix.keepLastTab":
case "browser.tabs.tabClipWidth":
adjustOn2ndTab.closeButton(1);
break;
case "extensions.tabmix.tabBarPosition":
if (this.tabBarPositionChanged(gTabmixPrefs.getIntPref(prefName))) {
if (window.fullScreen)
TMP_eventListener.onFullScreen(true);
TMupdateSettings(false);
}
break;
case "extensions.tabmix.useGreyCloseButton":
this.tabCloseButton();
break;
case "extensions.tabmix.undoClose":
if (!tabxPrefs.getBoolPref("undoClose")) {
gTabmixPrefs.setIntPref("browser.sessionstore.max_tabs_undo", 0);
}
else if (gTabmixPrefs.getIntPref("browser.sessionstore.max_tabs_undo") == 0)
gTabmixPrefs.clearUserPref("browser.sessionstore.max_tabs_undo");
break;
case "browser.sessionstore.max_tabs_undo":
prefValue = gTabmixPrefs.getIntPref(prefName);
while (prefValue < TMP_ClosedTabs.count) {
TMP_ClosedTabs.ssIsON ? TMP_ClosedTabs.getClosedTabAtIndex(TMP_ClosedTabs.count - 1) : getClosedTab("delete", TMP_ClosedTabs.count - 1);
}
if (tabxPrefs.getBoolPref("undoClose") != (prefValue > 0))
tabxPrefs.setBoolPref("undoClose", prefValue > 0);
TMP_ClosedTabs.setButtonDisableState();
break;
case "browser.warnOnRestart":
case "browser.warnOnQuit":
case "browser.sessionstore.resume_from_crash":
if (!gTabmixPrefs.getBoolPref(prefName))
return;
var TMP_sessionManager_enabled = tabxPrefs.getBoolPref("sessions.manager") ||
tabxPrefs.getBoolPref("sessions.crashRecovery");
if (TMP_sessionManager_enabled)
gTabmixPrefs.setBoolPref(prefName, false);
break;
case "browser.startup.page":
if (gTabmixPrefs.getIntPref(prefName) != 3)
return;
TMP_sessionManager_enabled = tabxPrefs.getBoolPref("sessions.manager") ||
tabxPrefs.getBoolPref("sessions.crashRecovery");
if (TMP_sessionManager_enabled)
gTabmixPrefs.setIntPref(prefName, 1);
break;
case "extensions.tabmix.sessions.manager":
case "extensions.tabmix.sessions.crashRecovery":
TMP_SessionStore.setService(2, false);
case "extensions.tabmix.sessions.save.closedtabs":
case "extensions.tabmix.sessions.save.history":
case "extensions.tabmix.sessionToolsMenu":
case "extensions.tabmix.closedWinToolsMenu":
SessionManager.updateSettings();
break;
case "extensions.tabmix.optionsToolMenu":
document.getElementById("tabmix-menu").hidden = !gTabmixPrefs.getBoolPref(prefName);
break;
case "browser.link.open_external":
case "browser.link.open_newwindow.restriction":
case "browser.link.open_newwindow":
this.setLink_openPrefs();
break;
case "extensions.tabmix.singleWindow":
this.setSingleWindowUI();
break;
case "extensions.tabmix.hideTabbar":
this.setAutoHidePref();
this.setTabBarVisibility(false);
break;
case "browser.tabs.autoHide":
this.setAutoHidePref();
break;
case "extensions.tabmix.newTabButton.position":
this.changeNewTabButtonSide(gTabmixPrefs.getIntPref(prefName));
break;
case "browser.ctrlTab.previews":
case "extensions.tabmix.lasttab.tabPreviews":
case "extensions.tabmix.lasttab.favorLeftToRightOrdering":
case "extensions.tabmix.lasttab.respondToMouseInTabList":
case "extensions.tabmix.lasttab.showTabList":
TMP_LastTab.ReadPreferences();
break;
case "extensions.treestyletab.tabbar.position":
TMP_setDragEvents(false);
break;
case "extensions.tabmix.reloadEvery.onReloadButton":
this.showReloadEveryOnReloadButton();
break;
default:
TMupdateSettings(false);
}
},
tabCloseButton: function() {
/* Mac from Firefox 2 and Linux from Firefox 3 don't use close.png */
if (/^Linux/.test(navigator.platform))
return;
// we have some exeptions here....
// classiccompact theme
// .... if we find more we need to add theme here or maybe add some pref??
if (/^Mac/.test(navigator.platform) && gTabmixPrefs.getCharPref("general.skins.selectedSkin") != "classiccompact")
return;
try {
var useNewCloseIcon = tabxPrefs.getBoolPref("useGreyCloseButton");
}
catch(er) { useNewCloseIcon = true; }
if (useNewCloseIcon) {
gBrowser.mTabContainer.setAttribute("closeIcon", "v3");
}
else
gBrowser.mTabContainer.removeAttribute("closeIcon");
},
toggleKey: function(keiID, prefName) {
var key = document.getElementById(keiID);
if (TMP_getBoolPref("", prefName, false)) {
if (key.hasAttribute("oncommand"))
key.removeAttribute("oncommand");
} else
key.setAttribute("oncommand", key.getAttribute("TM_oncommand"));
},
colorRules: {},
createColorRules: function TMP_PO_createColorRules() {
// find tab.css to insert our color rules into it.
// insert our rules into document.styleSheets[0] cause problem with other extensions
var ss = null;
for (var i = 0; i < document.styleSheets.length; ++i) {
if (document.styleSheets[i].href == "chrome://tabmixplus/skin/tab.css") {
ss = document.styleSheets[i];
break;
}
}
if (!ss)
ss = document.styleSheets[document.styleSheets.length-1];
this.tabStyleSheet = ss;
var styleRules = {
currentTab: { text: '.tabbrowser-tabs[currentTab=true][useCurrentColor=true] .tabbrowser-tab[selected="true"] .tab-text { color: #colorCode;}',
bg : '.tabbrowser-tabs[currentTab=true][useCurrentBGColor=true] .tabbrowser-tab[selected="true"],'+
'.tabbrowser-tabs[currentTab=true][useCurrentBGColor=true][tabonbottom] .tabs-bottom {background-color: #colorCode !important;}'},
unreadTab: { text: '.tabbrowser-tabs[unreadTab=true][useUnreadColor=true] .tabbrowser-tab:not([selected="true"]):not([visited]) .tab-text { color: #colorCode;}',
bg: '.tabbrowser-tabs[unreadTab=true][useUnreadBGColor=true] .tabbrowser-tab:not([selected="true"]):not([visited]){ background-color: #colorCode !important;}'},
otherTab: { text: '.tabbrowser-tabs[otherTab=true][useOtherColor=true]:not([unreadTab=true]) .tabbrowser-tab:not([selected="true"]) .tab-text,' +
'.tabbrowser-tabs[otherTab=true][useOtherColor=true] .tabbrowser-tab:not([selected="true"])[visited] .tab-text { color: #colorCode;}',
bg: '.tabbrowser-tabs[otherTab=true][useOtherBGColor=true]:not([unreadTab=true]) .tabbrowser-tab:not([selected="true"]),' +
'.tabbrowser-tabs[otherTab=true][useOtherBGColor=true] .tabbrowser-tab:not([selected="true"])[visited]{ background-color: #colorCode !important;}'},
progressMeter: { bg: '.tabbrowser-tabs[useProgressColor=true] .tabbrowser-tab .progress-bar { background-color: #colorCode !important;}'}
}
// Charter Toolbar extension add Object.prototype.toJSONString
// that break the use "for (var rule in styleRules)"
var j, rule;
var rules = ["currentTab", "unreadTab", "otherTab", "progressMeter"];
for (var j = 0; j < rules.length; j++) {
rule = rules[j];
this.setTabStyles("extensions.tabmix.styles." + rule, true);
var prefValues = this.tabStylePrefs[rule];
if (!prefValues)
continue;
var newRule, index;
if (rule != "progressMeter") {
newRule = styleRules[rule].text.replace("#colorCode",prefValues.textColor);
index = ss.insertRule(newRule, ss.cssRules.length);
this.colorRules[rule] = ss.cssRules[index];
}
newRule = styleRules[rule].bg.replace("#colorCode",prefValues.bgColor);
index = ss.insertRule(newRule, ss.cssRules.length);
this.colorRules[rule + "bg"] = ss.cssRules[index];
if (rule != "progressMeter")
this.toggleTabStyles(rule);
// in 0.3.0.605 we changed tab color from old pref to new pref
// old pref "extensions.tabmix.currentColor" type integer
// new pref "extensions.tabmix.currentColorCode" type string
//
// in 0.3.7.4 2008-12-24 we combined all style pref into one per type
// extensions.tabmix.styles.[TYPE NAME]
gPreventUpdate = true;
var ruleName = rule.replace(/Tab|Meter/,"");
var attrib = ruleName.charAt(0).toUpperCase() + ruleName.substr(1);
var oldPrefs = {italic: "italic" + attrib, bold: "bold" + attrib, underline: "underline" + attrib,
text: "use"+ attrib + "Color", textColor: ruleName + "ColorCode", textColorOLD: ruleName + "Color"}
const pBranch = Components.interfaces.nsIPrefBranch;
var needToUpdatePref = false;
var prefsToChange = {};
for (var oldPref in oldPrefs) {
var prefName = oldPrefs[oldPref] ,prefValue = null;
if (tabxPrefs.prefHasUserValue(prefName)) {
switch (tabxPrefs.getPrefType(prefName)) {
case pBranch.PREF_BOOL:
prefValue = tabxPrefs.getBoolPref(prefName);
break;
case pBranch.PREF_INT:
var colorCodes = ["#CF1919", "#0E36EF", "#DDDF0D", "#3F8F3E", "#E066FF", "#86E7EF",
"#FFFFFF", "#7F7F7F", "#000000", "#EF952C", "#FF82AB", "#7F4C0F", "#AAAAFF"];
var _value = tabxPrefs.getIntPref(prefName);
if (_value >= 0 && _value < 13)
prefValue = colorCodes[_value];
break;
case pBranch.PREF_STRING:
prefValue = tabxPrefs.getCharPref(prefName);
break;
}
tabxPrefs.clearUserPref(prefName);
if (prefValue != null) {
needToUpdatePref = true;
if (rule == "progressMeter")
oldPref = oldPref.replace("text", "bg");
prefsToChange[oldPref.replace("OLD", "")] = prefValue;
}
}
}
gPreventUpdate = false;
if (needToUpdatePref == true) {
this.converOldStylePrefs(rule, prefsToChange);
}
}
// from Firefox 3 tab-icon-image class have -moz-margin-start: value; -margin-end-value: value;
// we apply these value dynamically here to our tab-protect-icon tab-lock-icon class since each theme use different values
var icon = document.getAnonymousElementByAttribute(gBrowser.mCurrentTab, "class", "tab-icon-image");
if (icon) {
var marginStart = window.getComputedStyle(icon, null).marginLeft;
var marginEnd = window.getComputedStyle(icon, null).marginRight;
var iconRule = ".tabbrowser-tab > .tab-image-middle > .tab-icon > .tab-protect-icon," +
".tabbrowser-tab > .tab-image-middle > .tab-icon > .tab-lock-icon {" +
"-moz-margin-start: %S; -moz-margin-end: %S;}".replace("%S", marginStart).replace("%S", marginEnd);
ss.insertRule(iconRule, ss.cssRules.length);
}
try {
this.replaceThrobberRules();
} catch (ex) {TMP_ASSERT(ex);}
},
// update throbber for tab. for firefox 3.0.x - 3.6 there is one rule
// starting from 3.7+ - 2007-09-30 there are 10 rules
replaceThrobberRules: function TMP_PO_replaceThrobberRules() {
let browserCss;
for (let i = 0; i < document.styleSheets.length; ++i) {
if (document.styleSheets[i].href == "chrome://browser/skin/browser.css") {
browserCss = document.styleSheets[i];
break;
}
}
if (browserCss) {
let rulesCount = browserCss.cssRules.length;
let oldImage = "> .tab-icon-image";
let oldImageRe = new RegExp(oldImage);
let newImage = "> .tab-image-middle > .tab-icon > .tab-icon-image";
let newImageRe = new RegExp(newImage);
let oldText = "> .tab-text";
let oldTextRe = new RegExp(oldText);
let newText = "> .tab-image-middle > .tab-text-stack > .tab-text";
let newTextRe = new RegExp(newText);
for (let i = 0; i < rulesCount; ++i) {
let rule = browserCss.cssRules[i];
let selector = rule.selectorText;
if (oldImageRe.test(selector) && !newImageRe.test(selector)) {
let cssText = rule.cssText.replace(oldImage, newImage);
this.tabStyleSheet.insertRule(cssText, this.tabStyleSheet.cssRules.length);
}
else if (oldTextRe.test(selector) && !newTextRe.test(selector)) {
let cssText = rule.cssText.replace(oldText, newText);
this.tabStyleSheet.insertRule(cssText, this.tabStyleSheet.cssRules.length);
}
}
}
else {
tmLog('unable to finde "chrome://browser/skin/browser.css"');
}
delete this.tabStyleSheet;
},
converOldStylePrefs: function TMP_PO_converOldStylePrefs(prefName, oldPrefs) {
var prefString = tabxPrefs.getCharPref("styles." + prefName);
try {
prefValues = Components.utils.evalInSandbox("({" + prefString + "})" , new Components.utils.Sandbox("about:blank"));
} catch (ex) { return; } // nothing we can do
for (var item in oldPrefs)
prefValues[item] = oldPrefs[item];
var newprefValues = [];
for (item in prefValues) {
var comma = typeof(prefValues[item]) == "string" ? "'" : "";
newprefValues.push(item + ":" + comma + prefValues[item] + comma);
}
var newprefString = newprefValues.join(",");
if (newprefString != prefString)
tabxPrefs.setCharPref("styles." + prefName, newprefString);
},
defaultStylePrefs: { currentTab: "italic:false,bold:false,underline:false,text:true,textColor:'rgba(0,0,0,1)',bg:false,bgColor:'rgba(236,233,216,1)'",
unreadTab: "italic:true,bold:false,underline:false,text:true,textColor:'rgba(204,0,0,1)',bg:false,bgColor:'rgba(236,233,216,1)'",
otherTab: "italic:false,bold:false,underline:false,text:true,textColor:'rgba(0,0,0,1)',bg:false,bgColor:'rgba(236,233,216,1)'",
progressMeter: "bg:true,bgColor:'rgba(170,170,255,1)'"},
tabStylePrefs: {},
setTabStyles: function TMP_PO_setTabStyles(prefName, start) {
var ruleName = prefName.split(".").pop();
if (ruleName in this && this[ruleName] == "preventUpdate")
return;
this[ruleName] = "preventUpdate";
// Converts a color string in the format "#RRGGBB" to rgba(r,g,b,a).
function getRGBcolor(aColorCode, aOpacity) {
var newRGB = [];
var _length = aColorCode.length;
if (/^rgba|rgb/.test(aColorCode)) {
newRGB = aColorCode.replace(/rgba|rgb|\(|\)/g,"").split(",").splice(0, 4);
if (newRGB.length < 3)
return null;
for (var i = 0; i < newRGB.length; i++) {
if (isNaN(newRGB[i].replace(/[\s]/g,"") * 1))
return null ;
}
}
else if (/^#/.test(aColorCode) && _length == 4 || _length == 7) {
aColorCode = aColorCode.replace("#","");
var subLength = _length == 7 ? 2 : 1;
var newRGB = [];
for (var i = 0; i < 3; i++) {
var subS = aColorCode.substr(i*subLength, subLength);
if (_length == 4)
subS += subS;
var newNumber = parseInt(subS, 16);
if (isNaN(newNumber))
return null;
newRGB.push(newNumber);
}
}
else
return null;
var opacity = newRGB[3];
if (aOpacity != null || opacity == null || opacity < 0 || opacity > 1)
newRGB[3] = aOpacity || 1;
return "rgba(" + newRGB.join(",") + ")";
}
// styles format: italic:boolean, bold:boolean, underline:boolean,
// text:boolean, textColor:string, textOpacity:string,
// bg:boolean, bgColor:string, bgOpacity:striung
// if we don't catch the problem here it can break the rest of tabmix startup
try {
var defaultPrefValues = Components.utils.evalInSandbox("({" + this.defaultStylePrefs[ruleName] + "})" , new Components.utils.Sandbox("about:blank"));
} catch (ex) {
this.tabStylePrefs[ruleName] = null;
tmLog('Error in preference "' + prefName + '", tabmix was unable to set style');
TMP_ASSERT(ex);
return;
}
var prefString = gTabmixPrefs.getCharPref(prefName);
var prefValues = {};
if (gTabmixPrefs.prefHasUserValue(prefName)) {
var _prefString = prefString.split(",");
for (var i = 0; i < _prefString.length; i++) {
if (_prefString[i].indexOf(":") == -1 || _prefString[i].indexOf("Color") > -1
|| _prefString[i].indexOf("Opacity") > -1)
continue;
var item = _prefString[i].split(":");
if (/^true$|^false$/.test(item[1].replace(/[\s]/g,"")))
continue;
_prefString[i] = item[0] + ":" + null;
}
prefString = _prefString.join(",");
try {
var currentPrefValues = Components.utils.evalInSandbox("({" + prefString + "})" , new Components.utils.Sandbox("about:blank"));
}
catch (ex) {
tmLog('Error in preference "' + prefName + '", value was reset to default');
TMP_ASSERT(ex);
if (gTabmixPrefs.prefHasUserValue(prefName))
gTabmixPrefs.clearUserPref(prefName);
// set prev value to default so we can continue with this function
currentPrefValues = defaultPrefValues;
}
// make sure we have all the item
// if item is missing set it to default
var newprefValues = [];
for (var item in defaultPrefValues) {
var _value = currentPrefValues[item];
if (item.indexOf("Color") > -1) {
var opacity = item.replace("Color", "Opacity");
var opacityValue = opacity in currentPrefValues ? currentPrefValues[opacity] : null;
_value = getRGBcolor(_value, opacityValue);
}
else if (_value != null && typeof(_value) != "boolean") {
if (/^true$|^false$/.test(_value.replace(/[\s]/g,"")))
_value = _value == "true" ? true : false;
else
_value = null;
}
if (_value == null)
prefValues[item] = defaultPrefValues[item];
else
prefValues[item] = _value;
var comma = typeof(prefValues[item]) == "string" ? "'" : "";
newprefValues.push(item + ":" + comma + prefValues[item] + comma);
}
var newprefString = newprefValues.join(",");
if (newprefString != prefString)
gTabmixPrefs.setCharPref(prefName, newprefString);
}
else
prefValues = defaultPrefValues;
// we don't change attribute to stay compatible with theme that maybe use this values
var attrib = (ruleName.charAt(0).toUpperCase() + ruleName.substr(1)).replace(/Tab|Meter/,"");
var tabBar = gBrowser.mTabContainer;
if (ruleName != "progressMeter") {
TMP_setItem(tabBar, "bold" + attrib, prefValues.bold);
TMP_setItem(tabBar, "italic" + attrib, prefValues.italic);
TMP_setItem(tabBar, "underline" + attrib, prefValues.underline);
TMP_setItem(tabBar, "use"+ attrib + "Color", prefValues.text);
TMP_setItem(tabBar, "use"+ attrib + "BGColor", prefValues.bg);
}
else
TMP_setItem(tabBar, "use"+ attrib + "Color", prefValues.bg);
var currentValue = this.tabStylePrefs[ruleName];
if (currentValue && !start) {
// we get here only when user changed pref value
if (currentValue.bgColor != prefValues.bgColor)
this.colorRules[ruleName + "bg"].style.setProperty("background-color",prefValues.bgColor, "important");
if (ruleName != "progressMeter") {
if (currentValue.textColor != prefValues.textColor)
this.colorRules[ruleName].style.setProperty("color",prefValues.textColor, null);
// changeing bold attribute can change tab width and effect tabBar scroll status
if (currentValue.bold != prefValues.bold) {
tabBarScrollStatus();
checkBeforeAndAfter();
}
}
}
this.tabStylePrefs[ruleName] = prefValues;
delete this[ruleName];
},
toggleTabStyles: function(prefName) {
var ruleName = prefName.split(".").pop();
gBrowser.mTabContainer.setAttribute(ruleName, tabxPrefs.getBoolPref(ruleName));
var attrib = (ruleName.charAt(0).toUpperCase() + ruleName.substr(1)).replace("Tab","");
var boldStyle = gBrowser.mTabContainer.getAttribute(attrib);
if (boldStyle == "true") {
tabBarScrollStatus();
checkBeforeAndAfter();
}
},
setLink_openPrefs: function() {
if (!gSingleWindowMode)
return;
function updateStatus(pref, testVal, test, newVal) {
try {
var prefValue = gTabmixPrefs.getIntPref(pref);
test = test ? prefValue == testVal : prefValue != testVal
}
catch(e){ test = true; }
if (test)
gTabmixPrefs.setIntPref(pref, newVal);
}
updateStatus("browser.link.open_external", 2, true, 3);
updateStatus("browser.link.open_newwindow.restriction", 0, false, 0);
updateStatus("browser.link.open_newwindow", 2, true, 3);
},
// code for Single Window Mode...
// disable the "Open New Window action
//disable & hides some menuitem
setSingleWindowUI: function() {
gSingleWindowMode = TMP_getBoolPref(tabxBranch, "singleWindow", false);
var newWindowButton = document.getElementById("new-window-button");
if (newWindowButton)
newWindowButton.setAttribute("disabled", gSingleWindowMode);
var openLink = document.getElementById("context-openlink");
if (openLink)
openLink.setAttribute("disabled", gSingleWindowMode);
var menuItem;
var menuFile = document.getElementById("menu_FilePopup");
if (menuFile) {
menuItem = menuFile.getElementsByAttribute("command", "cmd_newNavigator")[0];
if (menuItem)
menuItem.setAttribute("hidden", gSingleWindowMode);
}
var frameMenu = document.getElementById("frame");
if (frameMenu) {
menuItem = frameMenu.getElementsByAttribute("oncommand", "gContextMenu.openFrame();")[0];
if (menuItem)
menuItem.setAttribute("hidden", gSingleWindowMode);
}
document.getElementById("tmOpenInNewWindow").hidden = gSingleWindowMode;
},
setMenuIcons: function() {
function setClass(items, hideIcons) {
if (hideIcons)
for (var i = 0; i < items.length; ++i)
items[i].removeAttribute("class");
else
for ( i = 0; i < items.length; ++i)
items[i].setAttribute("class", items[i].getAttribute("tmp_iconic"));
}
var hideIcons = TMP_getBoolPref(tabxBranch, "hideIcons", false);
var iconicItems = document.getElementsByAttribute("tmp_iconic", "*");
setClass(iconicItems, hideIcons);
iconicItems = gBrowser.tabContextMenu.getElementsByAttribute("tmp_iconic", "*");
setClass(iconicItems, hideIcons);
},
setAutoHidePref: function() {
gHideTabBar = tabxPrefs.getIntPref("hideTabbar");
var autoHide = gHideTabBar != 0;
if (autoHide != gTabmixPrefs.getBoolPref("browser.tabs.autoHide"))
gTabmixPrefs.setBoolPref("browser.tabs.autoHide", autoHide);
},
setTabBarVisibility: function TMP_PO_setTabBarVisibility(onFullScreenExit) {
if (gHideTabBar == 2) {
TMP_setStripVisibilityTo(false);
}
else if (!gBrowser.getStripVisibility() || onFullScreenExit) {
// if we are in multi-row and we have more then one tab we need to initialize multi-row again
gBrowser.mTabContainer.collapsedTabs = 0;
setTabBarHeight(1);
gBrowser.mTabContainer.removeAttribute("multibar");
var moreThenOneTab = gBrowser.mTabContainer.childNodes.length > 1;
if (onFullScreenExit) // from firefox 3.0 tab strip is collapsed by set moz-collapsed to true on full screen
gBrowser.mStrip.setAttribute("moz-collapsed", false);
else if (moreThenOneTab || gHideTabBar == 0)
TMP_setStripVisibilityTo(true);
if (moreThenOneTab) {
tabBarScrollStatus();
gBrowser.mTabContainer.ensureTabIsVisible(gBrowser.mTabContainer.selectedIndex);
checkBeforeAndAfter();
//XXX underline the label bleed over the end when tab is to small and we have close button on the tab !!!!????
toggleUnderlineTabsLabel();
}
}
},
changeNewTabButtonSide: function(aPosition) {
var tabBar = gBrowser.mTabContainer;
tabBar._checkNewtabButtonVisibility = gIsFirefox35 && tabxPrefs.getBoolPref("newTabButton") && aPosition == 2;
var newTabButton = document.getAnonymousElementByAttribute(tabBar, "id", "tabs-newbutton-box");
// if we don't find tabs-newbutton-box prbebly some theme changed our binding
if (!newTabButton)
return;
tabBar._rightNewTabButton = newTabButton;
var buttonOnLeftSide = aPosition == 0;
if (buttonOnLeftSide) {
tabBar.setAttribute("newtab_side", "left");
var leftContainer = document.getAnonymousElementByAttribute(tabBar, "class", "tabs-newTab");
if (leftContainer)
leftContainer.appendChild(newTabButton);
}
else {
tabBar.setAttribute("newtab_side", aPosition == 1 ? "right" : "afterlast");
var allTabsButton = document.getAnonymousElementByAttribute(tabBar, "class", "tabs-alltabs-stack");
// if we don't find allTabsButton prbebly some them changed our binding
// look at Vista-aero 2.0.0.46 for example.
if (allTabsButton)
allTabsButton.parentNode.insertBefore(newTabButton, allTabsButton);
}
},
tabBarPositionChanged: function(aPosition) {
if (aPosition > 1 || (aPosition != 0 && "TreeStyleTabBrowser" in window)) {
tabxPrefs.setIntPref("tabBarPosition", 0);
return false;
}
if (gTabbarPosition == aPosition)
return false;
gTabbarPosition = aPosition;
gBrowser.mTabDropIndicatorBar.firstChild.removeAttribute("style");
var tabsToolbar = document.getElementById("tabs-toolbar");
if (gisToolbarMode && tabsToolbar) {
if (gTabbarPosition == 1) {// bottom
var bottomToolbox = document.getElementById("bottom-toolbox");
if (!bottomToolbox) {
bottomToolbox = document.createElement("toolbox");
bottomToolbox.setAttribute("id", "bottom-toolbox");
browser = document.getElementById("browser");
browser.parentNode.insertBefore(bottomToolbox, browser.nextSibling);
}
bottomToolbox.appendChild(tabsToolbar);
}
else {// top
// to prevent the toolbar from rebuild we remove currentset and defaultset attribute
// befro we move the toolbar back to navigator-toolbox
var currentSet = tabsToolbar.getAttribute("currentset");
tabsToolbar.removeAttribute("currentset");
var defaultSet = tabsToolbar.getAttribute("defaultset");
tabsToolbar.removeAttribute("defaultset");
document.getElementById("navigator-toolbox").appendChild(tabsToolbar);
if (currentSet)
tabsToolbar.setAttribute("currentset", currentSet);
if (defaultSet)
tabsToolbar.setAttribute("defaultset", defaultSet);
}
}
return true;
},
// Show Reload Every menu on Reload button
showReloadEveryOnReloadButton: function() {
let reloadButton = document.getElementById("reload-button");
if (!reloadButton)
return;
let show = gTabmixPrefs.getBoolPref("extensions.tabmix.reloadEvery.onReloadButton");
let popup = document.getElementById("autoreload_popup_reloadButton");
if (show && !popup) {
let clonePopup = document.getElementById("autoreload_popup").cloneNode(true);
clonePopup.setAttribute("id", "autoreload_popup_reloadButton");
clonePopup.setAttribute("position", "after_start");
reloadButton.appendChild(clonePopup);
}
else if (!show && popup)
popup.parentNode.removeChild(popup);
TMP_setItem(reloadButton, "type", show ? "menu-button" : null);
},
// we replace some Tabmix settings with Firefox settings
updateSettings: function() {
gPreventUpdate = true;
if (tabxPrefs.prefHasUserValue("undoCloseCache")) {
var max_tabs_undo = tabxPrefs.getIntPref("undoCloseCache");
tabxPrefs.clearUserPref("undoCloseCache");
gTabmixPrefs.setIntPref("browser.sessionstore.max_tabs_undo", max_tabs_undo);
}
// remove disp=attd&view=att it's make problem with gMail
if (tabxPrefs.prefHasUserValue("filetype")) {
var filetype = tabxPrefs.getCharPref("filetype");
filetype = filetype.replace("/disp=attd&view=att/","").replace(" ", " ").replace(/^\s+|\s+$/g, "");
tabxPrefs.setCharPref("filetype", filetype);
}
// 2008-08-17
if (tabxPrefs.prefHasUserValue("opentabfor.search")) {
gTabmixPrefs.setBoolPref("browser.search.openintab", tabxPrefs.getBoolPref("opentabfor.search"));
tabxPrefs.clearUserPref("opentabfor.search");
}
// 2008-09-23
if (tabxPrefs.prefHasUserValue("keepWindow")) {
gTabmixPrefs.setBoolPref("browser.tabs.closeWindowWithLastTab", !tabxPrefs.getBoolPref("keepWindow"));
tabxPrefs.clearUserPref("keepWindow");
}
// 2008-09-23
if (gTabmixPrefs.prefHasUserValue("browser.ctrlTab.mostRecentlyUsed")) {
gTabmixPrefs.setBoolPref("browser.ctrlTab.previews", gTabmixPrefs.getBoolPref("browser.ctrlTab.mostRecentlyUsed"));
gTabmixPrefs.clearUserPref("browser.ctrlTab.mostRecentlyUsed");
}
// 2008-09-28
if (tabxPrefs.prefHasUserValue("lasttab.handleCtrlTab")) {
gTabmixPrefs.setBoolPref("browser.ctrlTab.previews", tabxPrefs.getBoolPref("lasttab.handleCtrlTab"));
tabxPrefs.clearUserPref("lasttab.handleCtrlTab");
}
// 2008-11-29
if (tabxPrefs.prefHasUserValue("maxWidth")) {
gTabmixPrefs.setIntPref("browser.tabs.tabMaxWidth", tabxPrefs.getIntPref("maxWidth"));
tabxPrefs.clearUserPref("maxWidth");
}
// 2008-11-29
if (tabxPrefs.prefHasUserValue("minWidth")) {
gTabmixPrefs.setIntPref("browser.tabs.tabMinWidth", tabxPrefs.getIntPref("minWidth"));
tabxPrefs.clearUserPref("minWidth");
}
// 2009-01-31
if (tabxPrefs.prefHasUserValue("newTabButton.leftside")) {
tabxPrefs.setIntPref("newTabButton.position", tabxPrefs.getBoolPref("newTabButton.leftside") ? 0 : 2);
tabxPrefs.clearUserPref("newTabButton.leftside");
}
// 2009-10-10
// swap prefs --> warn when closing window "extensions.tabmix.windows.warnOnClose" replaced with "browser.tabs.warnOnClose"
// warn when closing tabs "browser.tabs.warnOnClose" replaced with "extensions.tabmix.tabs.warnOnClose"
if (tabxPrefs.prefHasUserValue("windows.warnOnClose")) {
tabxPrefs.setBoolPref("tabs.warnOnClose", gTabmixPrefs.getBoolPref("browser.tabs.warnOnClose"));
gTabmixPrefs.setBoolPref("browser.tabs.warnOnClose", tabxPrefs.getBoolPref("windows.warnOnClose"));
tabxPrefs.clearUserPref("windows.warnOnClose");
}
// verify that all the prefs exist .....
this.addMissingPrefs();
gPreventUpdate = false;
},
// we call this function also from pref-tabmix.js
addMissingPrefs: function() {
const pBranch = Components.interfaces.nsIPrefBranch;
function _setPref(aType, aPref, aDefault) {
if (gTabmixPrefs.prefHasUserValue(aPref)) {
if (gTabmixPrefs.getPrefType(aPref) == aType)
return;
else
gTabmixPrefs.clearUserPref(aPref);
}
switch (aType) {
case pBranch.PREF_BOOL:
return TMP_getBoolPref("", aPref, aDefault);
case pBranch.PREF_INT:
return TMP_getIntPref("", aPref, aDefault);
case pBranch.PREF_STRING:
return TMP_getCharPref("", aPref, aDefault);
}
}
_setPref(pBranch.PREF_BOOL, "browser.tabs.closeWindowWithLastTab", false); // exist in firefox version 3.5
_setPref(pBranch.PREF_BOOL, "browser.ctrlTab.previews", true); // exist in firefox version 3.5
_setPref(pBranch.PREF_INT, "browser.link.open_external", 3); // not exist in firefox from version 3.5
}
}
// adjust attribute when we close 2nd tab (we left with only one) or when we open 2nd tab
var adjustOn2ndTab = {
/* don't show close tab button if there is only one blank tab or we keep last tab
* or if tab width is smaller then pref and not in WidthFitTitle mode.
*/
closeButton: function adjust_closeButton(aNumTabs, oldTab) {
var tabBar = gBrowser.mTabContainer;
var tabs = tabBar.childNodes;
var aTab = aNumTabs == 2 && tabs[0] == oldTab && tabs.length > 1 ? tabs[1] : tabs[0];
if (tabs.length == aNumTabs &&
(TMP_getBoolPref(tabxBranch, "keepLastTab", false) || gBrowser.isBlankNotBusyTab(aTab)))
tabBar.setAttribute("hidebutton", "true");
// from Firefox 3.5+ tabBar._removingTabs holds tab that are about to remove
// when we add new tab before removeing the last one don't remove hidebutton attribute
else if (tabBar.hasAttribute("hidebutton") &&
(!gIsFirefox35 || tabs.length - gBrowser._removingTabs.length > 1))
tabBar.removeAttribute("hidebutton");
setTimeout( function(tabBar) {
// make sure not to check collapsed tab for width
var ltr = window.getComputedStyle(gBrowser, null).direction == "ltr";
var width = ltr ? tabBar.lastChild.boxObject.width : tabBar.firstChild.boxObject.width;
// 0 width is an invalid value and indicates an item without display,
// so ignore.
var tabClipWidth = TMP_getIntPref("", "browser.tabs.tabClipWidth", 140);
var attributeChanged = false;
if (addtabx != 5 || gWidthFitTitle || width > tabClipWidth || width == 0) {
if (tabBar.hasAttribute("tinywidth")) {
tabBar.removeAttribute("tinywidth");
attributeChanged = true;
}
}
else if (!tabBar.hasAttribute("tinywidth")) {
tabBar.setAttribute("tinywidth", "true");
attributeChanged = true;
}
if (attributeChanged) {
tabBarScrollStatus();
checkBeforeAndAfter();
}
}, 0, tabBar);
}
}
function TMP_getBoolPref(branch, prefname, def ) {
try {
return gTabmixPrefs.getBoolPref(branch+prefname);
}
catch(er) {
gTabmixPrefs.setBoolPref(branch+prefname, def);
return def;
}
}
function TMP_getIntPref(branch, prefname, def ) {
try {
return gTabmixPrefs.getIntPref(branch+prefname);
}
catch(er) {
gTabmixPrefs.setIntPref(branch+prefname, def);
return def;
}
}
function TMP_getCharPref(branch, prefname, def ) {
try {
return gTabmixPrefs.getCharPref(branch+prefname);
}
catch(er) {
gTabmixPrefs.setCharPref(branch+prefname, def);
return def;
}
}
var TMP_ProgressListener = {
startup: function TMP_PL_startup(tabBrowser) {
if (gIsFirefox35) {
eval("tabBrowser.swapBrowsersAndCloseOther ="+tabBrowser.swapBrowsersAndCloseOther.toString().replace(
'this.mTabListeners[ourIndex] = tabListener;',
'tabListener = TMP_ProgressListener.init(tabListener); \ $&'
));
}
if (gIsFirefox35 && tabBrowser.mTabFilters[0]) {
// remove exiasting event listeners
tabBrowser.webProgress.removeProgressListener(tabBrowser.mTabFilters[0]);
tabBrowser.mTabFilters[0].removeProgressListener(tabBrowser.mTabListeners[0]);
// Hook up our event listeners to the first browser
var tabListener = tabBrowser.mTabProgressListener(tabBrowser.selectedTab, tabBrowser.selectedBrowser, true);
tabListener = this.init(tabListener);
const filter = Components.classes["@mozilla.org/appshell/component/browser-status-filter;1"]
.createInstance(Components.interfaces.nsIWebProgress);
filter.addProgressListener(tabListener, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
tabBrowser.webProgress.addProgressListener(filter, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
tabBrowser.mTabListeners[0] = tabListener;
tabBrowser.mTabFilters[0] = filter;
}
else {
eval("tabBrowser.enterTabbedMode ="+tabBrowser.enterTabbedMode.toString().replace(
'filter.addProgressListener(listener, Components.interfaces.nsIWebProgress.NOTIFY_ALL);',
'listener = TMP_ProgressListener.init(listener); \ $&'
));
}
eval("tabBrowser.addTab ="+tabBrowser.addTab.toString().replace(
'var tabListener = this.mTabProgressListener(t, b, blank);',
'$& \ tabListener = TMP_ProgressListener.init(tabListener);'
));
},
init: function TMP_PL_init(progressListener) {
var _this = "TMP_ProgressListener."
function addToTheEnd(fnName, newString) {
var fnString = progressListener[fnName].toString();
fnString = fnString.substr(0, fnString.length - 2) + newString + "}";
eval("progressListener." + fnName + " = " + fnString);
}
addToTheEnd('onProgressChange',
'this.onStateChange(aWebProgress, aRequest);' +
_this + 'setTabProgress(this.mTab, aMaxTotalProgress, aCurTotalProgress);');
// we need to be compatible with XHTML Ruby Support
var fnName = "onStateChange";
var ruby = "__rubysupport__" + fnName;
if (ruby in progressListener)
fnName = ruby;
eval("progressListener." + fnName + " = " + progressListener[fnName].toString().replace(
'this.mTab.setAttribute("busy", "true");',
_this + 'setTabWidth(this.mTab, aRequest.QueryInterface(nsIChannel).URI.spec);'
+ '$&'
).replace(
'var location = aRequest.QueryInterface(nsIChannel).URI;',
_this + 'setUnreadTab(this.mTab); \ $&'
));
addToTheEnd(fnName,
_this + 'setAutoReload(this.mTab, this.mBrowser, aStateFlags);');
// XXX how to do this with Regexp and replace ?
var string = "if (this.mTabBrowser.mCurrentTab == this.mTab)";
var split_fn = progressListener[fnName].toString().split(string);
split_fn[1] += _this + 'updateSessionManager(this.mTab);'
eval("progressListener." + fnName + " = " + split_fn.join(string));
addToTheEnd('onLocationChange', _this + 'fixBug355253(this.mBrowser);')
return progressListener;
},
setTabProgress: function TMP_PL_setTabProgress(aTab, aMaxTotalProgress, aCurTotalProgress) {
if (gHideTabBar == 2 || aMaxTotalProgress < 1)
return;
var percentage = parseInt((aCurTotalProgress * 100) / aMaxTotalProgress);
if (percentage > 0 && percentage < 100)
aTab.setAttribute("tab-progress", percentage);
},
setTabWidth: function TMP_PL_setTabWidth(aTab, aLocation) {
var tabBar = aTab.parentNode;
var spacer = 0;
// at this stage only unhide the button if needed.
var buttonIsHidden = tabBar.hasAttribute("hidebutton");
var keepLastTab = tabxPrefs.getBoolPref("keepLastTab");
if (tabBar.childNodes.length == 1 && (buttonIsHidden || keepLastTab)) {
var hidebutton = (aLocation == "about:blank") || keepLastTab;
if (buttonIsHidden && !hidebutton)
spacer = 5;
TMP_setItem(tabBar, "hidebutton", hidebutton || null);
}
if (gHideTabBar != 2 && gWidthFitTitle && !aTab.hasAttribute("width") && aLocation != aTab.label) {
if (aTab.hasAttribute("newtab")) {
spacer = 5;
aTab.removeAttribute("newtab");
}
//XXX check if we need to use spacer
aTab.setAttribute("width", aTab.boxObject.width);
}
},
setUnreadTab: function TMP_PL_setUnreadTab(aTab) {
if (aTab.parentNode.childNodes.length == 1) {
var hidebutton = gBrowser.isBlankTab(aTab) || tabxPrefs.getBoolPref("keepLastTab");
TMP_setItem(aTab.parentNode, "hidebutton", hidebutton || null);
}
aTab.removeAttribute("tab-progress");
if (gTabmixPrefs.getBoolPref("extensions.tabmix.unreadTab") &&
aTab.hasAttribute("visited") &&
gTabmixPrefs.getBoolPref("extensions.tabmix.unreadTabreload") &&
!aTab.hasAttribute("dontremovevisited") &&
aTab.getAttribute("selected") != "true")
aTab.removeAttribute("visited");
// see gBrowser.openLinkWithHistory in tablib.js
if (aTab.hasAttribute("dontremovevisited"))
aTab.removeAttribute("dontremovevisited")
},
updateSessionManager: function TMP_PL_updateSessionManager(aTab) {
if (!aTab.hasAttribute("busy"))
SessionManager.tabLoaded(aTab);
},
setAutoReload: function TMP_PL_setAutoReload(aTab, aBrowser, aStateFlags) {
const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
if ((aStateFlags & nsIWebProgressListener.STATE_IS_WINDOW) &&
(aStateFlags & nsIWebProgressListener.STATE_STOP)) {
if (aTab.autoReloadURI)
gBrowser.onTabReloaded(aTab, aBrowser);
// disabled name for locked tab, so locked tab don't get reuse
if (aTab.getAttribute("locked") && aBrowser.contentWindow.name)
aBrowser.contentWindow.name = "";
}
},
// XXX temp fix to bug 355253
// recently closed tabs doesn't saved closed tab if it have "about:blank" first in history.
fixBug355253: function TMP_PL_fixBug355253(aBrowser) {
var history = aBrowser.webNavigation.sessionHistory;
if (history && history.count == 2 && history.index == 1 &&
history.getEntryAtIndex(0, false).URI.spec == "about:blank") {
aBrowser.observe(null, "browser:purge-session-history", null);
var backCommand = document.getElementById("Browser:Back");
if (backCommand)
backCommand.setAttribute("disabled", "true");
}
}
}
var TMP_TabGroupsManager = {
init: function (tabBar) {
// for firefox 3.0
// var tabBar = gBrowser.mTabContainer;
tabBar.__defineGetter__("lastTabVisible", function () {return TabGroupsManagerApiForTMPVer1.lastTabVisible;});
// replace gBrowser.mTabContainer.lastChild with current group lastChild
var selectedGroupLastChild = "TabGroupsManagerApiVer1.lastTab";
eval("tabBar.adjustNewtabButtonvisibility ="+tabBar.adjustNewtabButtonvisibility.toString().replace(
/this\.lastChild/g, selectedGroupLastChild
));
var _getter = tabBar.__lookupGetter__("lastTabRowNumber");
eval("_getter ="+_getter.toString().replace("this.lastChild", selectedGroupLastChild));
tabBar.__defineGetter__("lastTabRowNumber", _getter);
// replace gBrowser.mTabs or gBrowser.mTabContainer.childNodes with current group tabs
var selectedGroupTabs = "TabGroupsManagerApiVer1.visibleTabs";
eval("tabBar.adjustScrollTabsRight ="+tabBar.adjustScrollTabsRight.toString().replace(
/this\.childNodes/g, selectedGroupTabs
));
eval("tabBar.rowScroll ="+tabBar.rowScroll.toString().replace("this.childNodes", selectedGroupTabs));
_getter = tabBar.__lookupGetter__("collapsedTabs");
var _setter = tabBar.__lookupSetter__("collapsedTabs");
tabBar.__defineGetter__("collapsedTabs", _getter);
eval("_setter ="+_setter.toString().replace("this.childNodes", selectedGroupTabs));
tabBar.__defineSetter__("collapsedTabs", _setter);
tabBar.__defineGetter__("topTabY", this._getTopTabY);
// only allow to show tabs from the current group
eval("tabBar.isTabVisible="+tabBar.isTabVisible.toString().replace(
'this.childNodes', selectedGroupTabs
).replace(
'{',
'{aIndex = TabGroupsManagerApiVer1.getIndexInSelectedGroupFrom_tPos(aIndex);'
));
eval("tabBar.ensureTabIsVisible="+tabBar.ensureTabIsVisible.toString().replace(
'this.childNodes', selectedGroupTabs
).replace(
'const tabs',
'aIndex = TabGroupsManagerApiVer1.getIndexInSelectedGroupFrom_tPos(aIndex); $&'
));
eval("tabBar._notifyBackgroundTab="+tabBar._notifyBackgroundTab.toString().replace(
'this.childNodes', selectedGroupTabs
).replace(
'this.selectedIndex >= this.collapsedTabs',
'TabGroupsManagerApiVer1.getIndexInSelectedGroupFrom_tPos(this.selectedIndex) >= this.collapsedTabs'
));
// make scrool button show hidden tabs only from the current group
eval("createCommonList="+createCommonList.toString().replace(
'tabs = gBrowser.mTabs;',
'tabs = side ? ' + selectedGroupTabs + ' : gBrowser.mTabs;'
));
eval("TMP_Places.openGroup="+TMP_Places.openGroup.toString().replace("tabBar.childNodes", selectedGroupTabs));
eval("toggleUnderlineTabsLabel="+toggleUnderlineTabsLabel.toString().replace('tabBar.childNodes', selectedGroupTabs));
eval("TMP_eventListener.onTabOpen="+TMP_eventListener.onTabOpen.toString().replace(
'this.onTabOpen_updateTabBar();',
'try {if (TabGroupsManager.apiEnabled) TabGroupsManager.eventListener.onTabOpen(aEvent);} catch(e) { }'
));
eval("TMP_eventListener.onTabClose="+TMP_eventListener.onTabClose.toString().replace(
'this.onTabClose_updateTabBar(aTab);',
'try {TabGroupsManager.eventListener.onTabClose(aEvent);} catch(e) { }'
));
eval("TMP_eventListener.onTabClose_updateTabBar="+TMP_eventListener.onTabClose_updateTabBar.toString().replace(
'aTab._tPos < tabBar.collapsedTabs',
'TabGroupsManagerApiVer1.getIndexInSelectedGroupFromTab(aTab) < tabBar.collapsedTabs'
));
eval("TabDNDObserver.onDragOver="+TabDNDObserver.onDragOver.toString().replace(
'this.getNewIndex(event)',
'TMP_TabGroupsManager._getDNDIndex(event)'
));
eval("TabDNDObserver.onDrop="+TabDNDObserver.onDrop.toString().replace(
'this.getNewIndex(event)',
'TMP_TabGroupsManager._getDNDIndex(event)'
).replace(
'oldIndex < firstVisibleIndex',
'TabGroupsManagerApiVer1.getIndexInSelectedGroupFrom_tPos(oldIndex) < firstVisibleIndex'
).replace(
'gBrowser.mTabs[firstVisibleIndex - 1]',
selectedGroupTabs + '[firstVisibleIndex - 1]'
));
eval("TabDNDObserver.onDragEnd="+TabDNDObserver.onDragEnd.toString().replace('tabBar.childNodes', selectedGroupTabs));
eval("TabDNDObserver.onDragExit="+TabDNDObserver.onDragExit.toString().replace(
'if (target)',
'if (target && !(/^TabGroupsManager/.test(target.id)))'
));
eval("TabDNDObserver.getNewIndex="+TabDNDObserver.getNewIndex.toString().replace(
'tabBar.childNodes', selectedGroupTabs
).replace(
/event\.target\._tPos/g,
'TabGroupsManagerApiVer1.getIndexInSelectedGroupFromTab(event.target)'
).replace(
/isTabVisible\(i\)/g,
'isTabVisible(tabs[i]._tPos)'
));
eval("getRowHeight="+getRowHeight.toString().replace(
'tabBar.childNodes', selectedGroupTabs
).replace(
/tabBar\.lastChild/g, selectedGroupLastChild
));
eval("tabBarWidthChange="+tabBarWidthChange.toString().replace(
'tabBar.childNodes', selectedGroupTabs
).replace(
'tabBar.ensureTabIsVisible(index);',
'tabBar.ensureTabIsVisible(tabs[index]._tPos);'
).replace(
'tabBar.lastChild', selectedGroupLastChild
));
eval("adjustOn2ndTab.closeButton="+adjustOn2ndTab.closeButton.toString().replace(
'tabBar.lastChild', selectedGroupLastChild
).replace(
'tabBar.firstChild', 'TabGroupsManagerApiVer1.firstTab'
));
// **************************** for Session Manager ****************************
eval("SessionData.getTabProperties="+SessionData.getTabProperties.toString().replace(
'return tabProperties;',
'if (aTab.group && aTab.group.id) \
tabProperties += " tabgroups-data=" + encodeURI(aTab.group.id + " " + aTab.group.name); \
$&'
));
eval("SessionManager.saveOneWindow="+SessionManager.saveOneWindow.toString().replace(
'if (caller == "windowbackup")',
<![CDATA[
this.saveAllGroupsData(null, rdfNodeThisWindow);
$&
]]>
));
eval("SessionManager.loadOneWindow="+SessionManager.loadOneWindow.toString().replace(
'var lastSelectedIndex = restoreSelect ? this.getIntValue(rdfNodeWindow, "selectedIndex") : 0;',
'$&\
var [_restoreSelect, _lastSelectedIndex] = [restoreSelect, lastSelectedIndex];\
[restoreSelect, lastSelectedIndex] = [false, 0];'
).replace(
'var selectedTabLoaded;',
<![CDATA[
try {
let jsonText = this.getLiteralValue(rdfNodeWindow, "tgm_jsonText");
if (jsonText)
TMP_ClosedTabs.ss.setWindowValue(window, "TabGroupsManagerAllGroupsData", decodeURI(jsonText));
TabGroupsManager.session.groupRestored = 0;
TabGroupsManager.session.restoreGroupsAndSleepingGroupsAndClosedGroups();
} catch (ex) {TMP_ASSERT(ex);}
$&
]]>
).replace(
'if (this.saveClosedtabs)',
<![CDATA[
if (_restoreSelect && (overwrite || (!concatenate && !currentTabIsBalnk)))
this.updateSelected(newIndex + _lastSelectedIndex, overwrite || caller=="firstwindowopen" || caller=="windowopenebytabmix");
$&
]]>
));
eval("SessionManager.loadOneTab="+SessionManager.loadOneTab.toString().replace(
'var savedHistory = this.loadTabHistory(rdfNodeSession, webNav.sessionHistory);',
<![CDATA[
$&
try {
var tabgroupsData = TMP_SessionStore._getAttribute({xultab: tabProperties}, "tabgroups-data");
if (tabgroupsData) {
let [groupId, groupName] = tabgroupsData.split(" ");
TMP_ClosedTabs.ss.setTabValue(aTab, "TabGroupsManagerGroupId", groupId);
TMP_ClosedTabs.ss.setTabValue(aTab, "TabGroupsManagerGroupName", groupName);
}
TabGroupsManager.session.moveTabToGroupBySessionStore(aTab);
} catch (ex) {TMP_ASSERT(ex);}
]]>
));
eval("SessionManager.setNC_TM="+SessionManager.setNC_TM.toString().replace(
'for',
'rdfLabels.push("tgm_jsonText");\
$&'
));
SessionManager.saveAllGroupsData = this._saveAllGroupsData;
},
_getTopTabY: function () {
return this.tabstripInnerbox.boxObject.y + parseInt(window.getComputedStyle(this.tabstripInnerbox, null).paddingTop);
},
// get _tPos from group index
_getDNDIndex: function (aEvent) {
var indexInGroup = TabDNDObserver.getNewIndex(aEvent);
var lastIndex = TabGroupsManagerApiVer1.visibleTabs.length - 1;
if (indexInGroup < 0 || indexInGroup > lastIndex)
indexInGroup = lastIndex;
return TabGroupsManagerApiVer1.visibleTabs[indexInGroup]._tPos;
},
// for TabGroupsManager use
tabmixSessionsManager: function () {
return gTabmixPrefs.getBoolPref("extensions.tabmix.sessions.manager") &&
(!TMP_SessionStore.isAfterRestart() || "tabmixdata" in window)
},
// for TabGroupsManager use
_saveAllGroupsData: function (jsonText, windowNode) {
if (!this.enableBackup && !windowNode)
return;
try {
let value = jsonText || TMP_ClosedTabs.ss.getWindowValue(window, "TabGroupsManagerAllGroupsData");
if (!windowNode)
windowNode = gThisWin;
this.setLiteral(windowNode, "tgm_jsonText", encodeURI(value));
this.saveStateDelayed();
} catch (ex) {
TMP_ASSERT(ex);
}
}
}